﻿namespace TanzimSaqib.NoBrainer
{
    using System;
    using System.Linq;
    using System.Web;

    public class Engine
    {
        public static string CmsXmlDirectory { get; private set; }
        internal static string XmlFileFilters { get; private set; }
        internal static string ExtensionsForStitching { get; private set; }
        private static string[] Extensions { get; set; }

        /// <summary>
        /// This method initializes NoBrainer framework, hence it should be the first method to execute. The most suitable place to call this method is inside Application_Start of Global.asax file.
        /// </summary>
        /// <param name="cacheProvider">An implementation of ICacheProvider</param>
        /// <param name="cmsXmlDirectory">Any path relative to the web folder. Example: CmsXml</param>
        /// <param name="xmlFileFilters">File extensions that NoBrainer will parse to extract CMS data. Example: *.xml</param>
        public static void Boot(Func<ICacheProvider> cacheProvider, string cmsXmlDirectory, string xmlFileFilters, string extensionsForStitching)
        {
            "NoBrainer: The ICacheProvider implementation was failed to initialize at Engine.Boot()".InvalidOperation(() => CacheManager.Instance = cacheProvider.Invoke());

            Boot(cmsXmlDirectory, xmlFileFilters, extensionsForStitching);
        }

        private static void Boot(string cmsXmlDirectory, string xmlFileFilters, string extensionsForStitching)
        {
            // TODO: Transfer to a resource file
            "NoBrainer: Directory location for CMS XML must be specified at Engine.Boot()".Null(cmsXmlDirectory);
            "NoBrainer: File extension to parse inside CMS XML directory must be specified at Engine.Boot(). Specify onle one extension. Example: xml".Null(xmlFileFilters);
            "NoBrainer: Specify extensions for HTML Stitching at Engine.Boot(). Use something random if you do not intend to use this feature. Example: html, htm".Null(extensionsForStitching);

            CmsXmlDirectory = cmsXmlDirectory;
            XmlFileFilters = xmlFileFilters;
            ExtensionsForStitching = extensionsForStitching;

            var tokens = ExtensionsForStitching.Split(',');
            Extensions = new string[tokens.Length];

            var index = 0;
            foreach(var extension in tokens)
            {
                Extensions[index++] = extension.Trim().ToLowerInvariant();
            }            

            ContentSentinel.Watch(CmsXmlDirectory, XmlFileFilters);
            
            "Engine initialized.".Trace();
        }

        public static void Handle()
        {
            var ctx = HttpContext.Current;
            var url = ctx.Request.Url;
            var urlAbsolutePath = url.AbsolutePath;
            var query = url.Query;

            foreach (var extension in
                Extensions.Where(extension => urlAbsolutePath.ToLowerInvariant().Contains(extension)))
            {
                ctx.RewritePath(
                    string.IsNullOrEmpty(query) ? 
                        string.Format("~/NoBrainerProcessor.aspx?{0}={1}", Constants.URL, url.LocalPath) : 
                        string.Format("~/NoBrainerProcessor.aspx{0}&{1}={2}", query, Constants.URL, url.LocalPath));

                string.Format("Handling request: {0}", url).Trace();
            }
        }
    }
}
